package components.utils;

import boundary.display.EntityDisplayPanel;
import boundary.display.PEmployeeDisplay;
import boundary.display.PEnterpriseDisplay;
import boundary.display.PPersonDisplay;
import boundary.display.PSampleDisplay;
import boundary.display.PServiceRequestDisplay;
import boundary.display.PTestDisplay;
import boundary.management.PEmployeeManagment;
import boundary.management.PTestManagement;
import boundary.registration.DCustodyRegistration;
import boundary.registration.PEmployeeRegistration;
import boundary.registration.PEnterpriseRegistration;
import boundary.registration.PPersonRegistration;
import boundary.registration.PServiceRequestRegistration;
import boundary.registration.PTestRegistration;
import components.ButtonTabComponent;
import components.TabPanel;
import entity.Custody;
import entity.Client;
import entity.DatabaseTest;
import entity.Employee;
import entity.Entity;
import entity.Sample;
import entity.ServiceRequest;
import java.awt.Component;
import java.awt.Frame;
import javax.swing.JComboBox;
import javax.swing.JPasswordField;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;

public class ComponentFactory {
    
    public static final int PERSON_REGISTRATION = 0;
    public static final int ENTERPRISE_REGISTRATION = 1;
    public static final int SERVICE_REQUEST_REGISTRATION = 2;
    public static final int EMPLOYEE_MANAGEMENT = 3;
    public static final int EMPLOYEE_REGISTRATION = 4;
    public static final int TEST_MANAGEMENT = 5;
    public static final int TEST_REGISTRATION = 6;
    
    private static final String PERSON_REGISTRATION_TITLE = "Registro de Persona Natural";
    private static final String ENTERPRISE_REGISTRATION_TITLE = "Registro de Empresa";
    private static final String SERVICE_REQUEST_REGISTRATION_TITLE = "Registro de Solicitud";
    private static final String EMPLOYEE_MANAGEMENT_TITLE = "Administración de Empleados";
    private static final String EMPLOYEE_REGISTRATION_TITLE = "Registro de Empleado";
    private static final String TEST_MANAGEMENT_TITLE = "Administración de Análisis";
    private static final String TEST_REGISTRATION_TITLE = "Registro de Análisis";
    
    public static void attachVerifier(String message, JTextField component) {
        TextFieldVerifier textFieldVerifier = new TextFieldVerifier(message, component);
        component.setInputVerifier(textFieldVerifier);
        component.addActionListener(textFieldVerifier);
    }
    
    public static void attachVerifier(String message, JComboBox component) {
        ComboBoxVerifier comboBoxVerifier = new ComboBoxVerifier(message, component);
        component.setInputVerifier(comboBoxVerifier);
        component.addActionListener(comboBoxVerifier);
    }
    
    public static void attachVerifier(String message, JPasswordField component) {
        attachVerifier(message, (JTextField) component);
    }
    
    public static Custody registerLeftoverDisposal(Component parent, Sample sample) {
        DCustodyRegistration newDialog = new DCustodyRegistration((Frame) parent, true, sample,
                DCustodyRegistration.LEFTOVER_DISPOSAL);
        return newDialog.getNewCustody();
    }
    
    public static Custody registerStorage(Component parent, Sample sample) {
        DCustodyRegistration newDialog = new DCustodyRegistration((Frame) parent, true, sample, DCustodyRegistration.STORAGE);
        return newDialog.getNewCustody();
    }
    
    public static Custody registerDisposal(Component parent, Sample sample) {
        DCustodyRegistration newDialog = new DCustodyRegistration((Frame) parent, true, sample, DCustodyRegistration.DISPOSAL);
        return newDialog.getNewCustody();
    }
    
    /**
     * Adds a new panel of the specified type to the provided Tabbed Pane.
     * If a panel of the same type is already open, selects it.
     *
     * @param tabbedPane
     * @param panelType int flag found in Component Factory.
     */
    public static void addNewSingletonPanel(JTabbedPane tabbedPane, int panelType) {
        Class panelClass;
        String title;
        if (panelType == PERSON_REGISTRATION) {
            panelClass = PPersonRegistration.class;
            title = PERSON_REGISTRATION_TITLE;
        } else if (panelType == ENTERPRISE_REGISTRATION) {
            panelClass = PEnterpriseRegistration.class;
            title = ENTERPRISE_REGISTRATION_TITLE;
        } else if (panelType == SERVICE_REQUEST_REGISTRATION) {
            panelClass = PServiceRequestRegistration.class;
            title = SERVICE_REQUEST_REGISTRATION_TITLE;
        } else if (panelType == EMPLOYEE_MANAGEMENT) {
            panelClass = PEmployeeManagment.class;
            title = EMPLOYEE_MANAGEMENT_TITLE;
        }else if (panelType == EMPLOYEE_REGISTRATION) {
            panelClass = PEmployeeRegistration.class;
            title = EMPLOYEE_REGISTRATION_TITLE;
        } else if (panelType == TEST_MANAGEMENT) {
            panelClass = PTestManagement.class;
            title = TEST_MANAGEMENT_TITLE;
        } else if (panelType == TEST_REGISTRATION) {
            panelClass = PTestRegistration.class;
            title = TEST_REGISTRATION_TITLE;
        } else {
            System.err.println("Invalid openNewSingletonPanel request: " + panelType);
            return;
        }
        
        //See if there's a panel of this class already open.
        int alreadyOpenPosition = alreadyOpenPosition(tabbedPane, panelClass);
        if (alreadyOpenPosition == -1) {
            //Create and add new panel.
            TabPanel newPanel = createSingletonPanel(tabbedPane, panelType);
            addTabPanel(tabbedPane, newPanel, title);
        } else {
            tabbedPane.setSelectedIndex(alreadyOpenPosition);
        }
    }
    
    private static int alreadyOpenPosition(JTabbedPane tabbedPane, Class whichPanel) {
        int position = -1;
        for (int i = 0; i < tabbedPane.getTabCount(); i++) {
            Component currentPanel = tabbedPane.getComponentAt(i);
            if (currentPanel.getClass().equals(whichPanel)) {
                position = i;
                break;
            }
        }
        
        return position;
    }
    
    private static TabPanel createSingletonPanel(JTabbedPane tabbedPane, int panelType) {
        TabPanel newPanel;
        
        if (panelType == PERSON_REGISTRATION) {
            newPanel = new PPersonRegistration();
        } else if (panelType == ENTERPRISE_REGISTRATION) {
            newPanel = new PEnterpriseRegistration();
        } else if (panelType == SERVICE_REQUEST_REGISTRATION) {
            newPanel = new PServiceRequestRegistration();
        } else if (panelType == EMPLOYEE_MANAGEMENT) {
            newPanel = new PEmployeeManagment();
        } else if (panelType == EMPLOYEE_REGISTRATION){
            newPanel = new PEmployeeRegistration();
        } else if (panelType == TEST_MANAGEMENT) {
            newPanel = new PTestManagement();
        } else if (panelType == TEST_REGISTRATION) {
            newPanel = new PTestRegistration();
        } else {
            System.err.println("Invalid createPanel request: " + panelType);
            return null;
        }
        
        newPanel.setButtonTabComponent(new ButtonTabComponent(tabbedPane));
        
        return newPanel;
    }
    
    private static void addTabPanel(JTabbedPane tabbedPane, TabPanel tabPanel, String title) {
        if (tabbedPane != null && tabPanel != null) {
            tabbedPane.add(title, tabPanel);
            tabbedPane.setSelectedComponent(tabPanel);
            tabbedPane.setTabComponentAt(tabbedPane.getSelectedIndex(),
                    tabPanel.getButtonTabComponent());
        }
    }
    
    public static void addDisplayPanel(JTabbedPane tabbedPane, Entity entity) {
        int alreadyDisplayingPosition = alreadyDisplayingPosition(tabbedPane, entity);
        if (alreadyDisplayingPosition == -1) {
            EntityDisplayPanel newPanel = createEntityDisplayPanel(tabbedPane, entity);
            addTabPanel(tabbedPane, newPanel, entity.toString());
        } else {
            tabbedPane.setSelectedIndex(alreadyDisplayingPosition);
        }
    }
    
    private static int alreadyDisplayingPosition(JTabbedPane tabbedPane, Entity entity) {
        int position = -1;
        for (int i = 0; i < tabbedPane.getTabCount(); i++) {
            Component currentTab = tabbedPane.getComponentAt(i);
            if (currentTab instanceof EntityDisplayPanel) {
                EntityDisplayPanel entityDisplayPanel = (EntityDisplayPanel) currentTab;
                Entity currentEntity = entityDisplayPanel.getCurrentEntity();
                if (currentEntity.equals(entity)) {
                    position = i;
                    break;
                }
            }
        }
        
        return position;
    }
    
    private static EntityDisplayPanel createEntityDisplayPanel(JTabbedPane tabbedPane, Entity entity) {
        EntityDisplayPanel newPanel;
        
        if (entity instanceof Employee) {
            newPanel = new PEmployeeDisplay();
        } else if (entity instanceof Client) {
            Client client = (Client) entity;
            if (client.getType() == Client.PERSON) {
                newPanel = new PPersonDisplay();
            } else {
                newPanel = new PEnterpriseDisplay();
            }
        } else if (entity instanceof Sample) {
            newPanel = new PSampleDisplay();
        } else if (entity instanceof ServiceRequest) {
            newPanel = new PServiceRequestDisplay();
        } else if (entity instanceof DatabaseTest) {
            newPanel = new PTestDisplay();
        } else {
            return null;
        }
        
        newPanel.setButtonTabComponent(new ButtonTabComponent(tabbedPane));
        newPanel.setCurrentEntity(entity);
        
        return newPanel;
    }
    
}
